package cn.yzgy.yzgyoa.common.handler;

import cn.yzgy.yzgyoa.common.crsp.StatusCode;
import cn.yzgy.yzgyoa.common.crsp.Urmf;
import cn.yzgy.yzgyoa.common.service.impl.SysAlarmServiceImpl;
import cn.yzgy.yzgyoa.ucenter.entity.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 全局RuntimeException处理
 *
 * @author Yqsen
 * @version 0.0.1
 * @since 2019-8-16 09:32:54
 */
@Slf4j
@Order(1)
@ControllerAdvice
@RestControllerAdvice
public class GeneralRuntimeExceptionHandler {

    @Autowired
    private SysAlarmServiceImpl sysAlarmService;

    @ResponseBody
    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Urmf runtimeExceptionHandler(RuntimeException e, HttpServletRequest request) {
        log.error(e.getMessage(), e);
        log.error("RUNTIME_EXCEPTION_HANDLER: Path:[{}] StackTrace:[{}] Message:[{}]", request.getRequestURI(), e.getStackTrace()[0],e.getMessage());
        sysAlarmService.saveExceptions(e);
        return Urmf.fail(request.getRequestURI(), StatusCode.EXCEPTION, e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Urmf methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e, HttpServletRequest request) {
        Map<String, String> errorList = new LinkedHashMap<>();
        for (FieldError error : e.getBindingResult().getFieldErrors()) {
            log.error("REST_VALIDATE_EXCEPTION: PATH:{} | KEY:{} MSG:{} ", request.getRequestURI(), error.getField(), error.getDefaultMessage());
            errorList.put(error.getField(), error.getDefaultMessage());
        }
        return Urmf.fail(request.getRequestURI(), StatusCode.VALIDATION_FAILED, errorList);
    }

    @ResponseBody
    @ExceptionHandler(UnauthorizedException.class)
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public Urmf unauthorizedException(UnauthorizedException e, HttpServletRequest request) {
        log.error("USER_UNAUTHORIZED_EXCEPTION: Path:[{}] User:{} Message:[{}]",
                request.getRequestURI(),
                ((SysUser)(SecurityUtils.getSubject().getPrincipal())).getLoginName(),
                e.getMessage());
        return Urmf.fail(request.getRequestURI(), StatusCode.FORBIDDEN);
    }

    @ResponseBody
    @ExceptionHandler(UnauthenticatedException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public Urmf unauthorizedException(UnauthenticatedException e, HttpServletRequest request) {
        log.error("USER_UNAUTHENTICATED_EXCEPTION: Path:[{}] Message:[{}]",
                request.getRequestURI(),
                e.getMessage());
        return Urmf.fail(request.getRequestURI(), StatusCode.UN_AUTHORIZATION);
    }

}
